#include "DXCamera.h"
#include <d3d9.h>
#include <d3dx9.h>

DXCamera::DXCamera()
	:
m_EyePos(D3DXVECTOR3(5.0f, 5.0f, -5.0f)),    // Eye Position
m_TargetPos(D3DXVECTOR3(-0.5f, -0.5f, 0.5f)),  // Look Vectorfactor(1.0f) {}
m_UpVector(D3DXVECTOR3(0.0f, 1.0f, 0.0f)),      // Up Vector
m_RightVector(D3DXVECTOR3(1.0f, 0.0f, 0.0f)),   // Right VectorCCamera::~CCamera() {}
m_Mousing(false),
m_MoveSpeed(20.0f) {}

void DXCamera::SetUp(LPDIRECT3DDEVICE9 p_dx_Device)
{
	D3DXMatrixLookAtLH(&m_View, &m_EyePos, &m_TargetPos, &m_UpVector);
	p_dx_Device->SetTransform(D3DTS_VIEW, &m_View);

	D3DXMatrixPerspectiveFovLH(&m_Projection, D3DXToRadian(45), 640.0f / 480.0f, 1, 5000);
	p_dx_Device->SetTransform(D3DTS_PROJECTION, &m_Projection);

	m_ViewProj = m_View * m_Projection;
}

void DXCamera::updateViewMatrix(LPDIRECT3DDEVICE9 p_dx_Device)
{
	D3DXMATRIX view;
	D3DXMatrixIdentity( &view );

	D3DXVec3Normalize( &m_TargetPos, &m_TargetPos );
	D3DXVec3Cross( &m_RightVector, &m_UpVector, &m_TargetPos );
	D3DXVec3Normalize( &m_RightVector, &m_RightVector );
	D3DXVec3Cross( &m_UpVector, &m_TargetPos, &m_RightVector );
	D3DXVec3Normalize( &m_UpVector, &m_UpVector );

	view._11 = m_RightVector.x;
    view._12 = m_UpVector.x;
    view._13 = m_TargetPos.x;
	view._14 = 0.0f;

	view._21 = m_RightVector.y;
    view._22 = m_UpVector.y;
    view._23 = m_TargetPos.y;
	view._24 = 0.0f;

	view._31 = m_RightVector.z;
    view._32 = m_UpVector.z;
    view._33 = m_TargetPos.z;
	view._34 = 0.0f;

	view._41 = -D3DXVec3Dot( &m_EyePos, &m_RightVector );
	view._42 = -D3DXVec3Dot( &m_EyePos, &m_UpVector );
	view._43 = -D3DXVec3Dot( &m_EyePos, &m_TargetPos );
	view._44 =  1.0f;


	m_View = view;
	m_ViewProj = m_View * m_Projection;

	p_dx_Device->SetTransform( D3DTS_VIEW, &view ); 
}

void DXCamera::getRealTimeUserInput (HWND g_hWnd, float g_fElpasedTime)
{
	POINT mousePosit;
	GetCursorPos( &mousePosit );
	ScreenToClient( g_hWnd, &mousePosit );

    m_CurrentMousePosit.x = mousePosit.x;
    m_CurrentMousePosit.y = mousePosit.y;

	D3DXMATRIX matRotation;

    if( m_Mousing )
    {
		int nXDiff = (m_CurrentMousePosit.x - m_LastMousePosit.x);
        int nYDiff = (m_CurrentMousePosit.y - m_LastMousePosit.y);
        
        if( nYDiff != 0 )
		{
			D3DXMatrixRotationAxis( &matRotation, &m_RightVector, D3DXToRadian((float)nYDiff / 3.0f));
			D3DXVec3TransformCoord( &m_TargetPos, &m_TargetPos, &matRotation );
			D3DXVec3TransformCoord( &m_UpVector, &m_UpVector, &matRotation );
		}

		if( nXDiff != 0 )
		{
			D3DXMatrixRotationAxis( &matRotation, &D3DXVECTOR3(0,1,0), D3DXToRadian((float)nXDiff / 3.0f) );
			D3DXVec3TransformCoord( &m_TargetPos, &m_TargetPos, &matRotation );
			D3DXVec3TransformCoord( &m_UpVector, &m_UpVector, &matRotation );
		}
    }

    m_LastMousePosit.x = m_CurrentMousePosit.x;
    m_LastMousePosit.y = m_CurrentMousePosit.y;

	unsigned char keys[256];
	GetKeyboardState( keys );
    
    D3DXVECTOR3 tmpLook  = m_TargetPos;
	D3DXVECTOR3 tmpRight = m_RightVector;

	// Up Arrow Key - View moves forward
	if( keys[VK_UP] & 0x80 )
		m_EyePos -= tmpLook*-m_MoveSpeed*g_fElpasedTime;

	// Down Arrow Key - View moves backward
	if( keys[VK_DOWN] & 0x80 )
		m_EyePos += (tmpLook*-m_MoveSpeed)*g_fElpasedTime;

	// Left Arrow Key - View side-steps or strafes to the left
	if( keys[VK_LEFT] & 0x80 )
		m_EyePos -= (tmpRight*m_MoveSpeed)*g_fElpasedTime;

	// Right Arrow Key - View side-steps or strafes to the right
	if( keys[VK_RIGHT] & 0x80 )
		m_EyePos += (tmpRight*m_MoveSpeed)*g_fElpasedTime;

	// Home Key - View elevates up
	if( keys[VK_HOME] & 0x80 )
		m_EyePos.y += m_MoveSpeed*g_fElpasedTime; 

	// End Key - View elevates down
	if( keys[VK_END] & 0x80 )
		m_EyePos.y -= m_MoveSpeed*g_fElpasedTime;
}